home *** CD-ROM | disk | FTP | other *** search
- UNIT VOCTOOL;
- {* Unit - uses CT-VOICE.DRV. *}
- INTERFACE
- TYPE
- VOCFileTyp = File;
- CONST
- VOCToolVersion = 'v1.5';
- VOCBreakEnd = 0;
- VOCBreakNow = 1;
- VAR
- VOCStatusWord : WORD;
- VOCErrStat : WORD;
- VOCFileHeader : STRING;
- VOCFileHeaderLength : BYTE;
- VOCPaused : BOOLEAN;
- VOCDriverInstalled : BOOLEAN;
- VOCDriverVersion : WORD;
- VOCPtrToDriver : Pointer;
- OldExitProc : Pointer;
- PROCEDURE PrintVOCErrMessage;
- FUNCTION VOCGetBuffer(VAR VoiceBuff : Pointer; Voicefile : STRING):BOOLEAN;
- FUNCTION VOCFreeBuffer(VAR VoiceBuff : Pointer):BOOLEAN;
- FUNCTION VOCGetVersion:WORD;
- PROCEDURE VOCSetPort(PortNumber : WORD);
- PROCEDURE VOCSetIRQ(IRQNumber : WORD);
- FUNCTION VOCInitDriver:BOOLEAN;
- PROCEDURE VOCDeInstallDriver;
- PROCEDURE VOCSetSpeaker(OnOff:BOOLEAN);
- PROCEDURE VOCOutput(BufferAddress : Pointer);
- PROCEDURE VOCOutputLoop (BufferAddress : Pointer);
- PROCEDURE VOCStop;
- PROCEDURE VOCPause;
- PROCEDURE VOCContinue;
- PROCEDURE VOCBreakLoop(BreakMode : WORD);
- IMPLEMENTATION
- USES DOS,Crt;
- TYPE
- TypeCastType = ARRAY [0..6000] of Char;
- VAR
- Regs : Registers;
- PROCEDURE PrintVOCErrMessage;
- {* INPUT : None
- * OUTPUT : None
- * PURPOSE : Displays SB error as text; no change to error status. }
- BEGIN
- CASE VOCErrStat OF
- 100 : Write(' Driver file CT-VOICE.DRV not found ');
- 110 : Write(' No memory available for driver file ');
- 120 : Write(' False driver file ');
- 200 : Write(' VOC file not found ');
- 210 : Write(' No memory available for driver file ');
- 220 : Write(' File not in VOC format ');
- 300 : Write(' Memory allocation error occurred ');
- 400 : Write(' No sound blaster card found ');
- 410 : Write(' False port address used ');
- 420 : Write(' False interrupt used ');
- 500 : Write(' No loop in process ');
- 510 : Write(' No sample for output ');
- 520 : Write(' No sample available ');
- END;
- END;
-
- FUNCTION Exists (Filename : STRING):BOOLEAN;
- {* INPUT : Filename as string
- * OUTPUT : TRUE if file is available, FALSE if not
- * PURPOSE : Checks for availability of file then returns Boolean exp. }
- VAR
- F : File;
- BEGIN
- Assign(F,Filename);
- {$I-}
- Reset(F);
- Close(F);
- {$I+}
- Exists := (IoResult = 0) AND (Filename <> '');
- END;
- PROCEDURE AllocateMem (VAR Pt : Pointer; Size : LongInt);
- {* INPUT : Buffer variable as pointer, buffer size as LongInt
- * OUTPUT : Pointer to buffer in variable or NIL
- * PURPOSE : Reserves as many bytes as Size allows, then moves pointer in
- the Pt variable. If not enough memory is available, Pt = NIL. }
- VAR
- SizeIntern : WORD;
- BEGIN
- Inc(Size,15);
- SizeIntern := (Size shr 4);
- Regs.AH := $48;
- Regs.BX := SizeIntern;
- MsDos(Regs);
- IF (Regs.BX <> SizeIntern) THEN Pt := NIL
- ELSE Pt := Ptr(Regs.AX,0);
- END;
- FUNCTION CheckFreeMem (VAR VoiceBuff : Pointer; VoiceSize : LongInt):BOOLEAN;
- {* INPUT : Buffer variable as pointer, size as LongInt
- * OUTPUT : Pointer to buffer, TRUE/FALSE, after AllocateMem
- * PURPOSE : Checks for sufficient memory to store a VOC file. }
- BEGIN
- AllocateMem(VoiceBuff,VoiceSize);
- CheckFreeMem := VoiceBuff <> NIL;
- END;
- FUNCTION VOCGetBuffer (VAR VoiceBuff : Pointer; Voicefile : STRING):BOOLEAN;
- {* INPUT : Buffer variable as pointer, file name as string
- * OUTPUT : Pointer to buffer with VOC data, TRUE/FALSE
- * PURPOSE : Loads a file into memory and returns TRUE if file loaded
- successfully, and FALSE if not. }
- VAR
- SampleSize : LongInt;
- FPresent : BOOLEAN;
- VFile : VOCFileTyp;
- Segs : WORD;
- Read : WORD;
- BEGIN
- FPresent := Exists(VoiceFile);
- { VOC file not found }
- IF Not(FPresent) THEN BEGIN
- VOCGetBuffer := FALSE;
- VOCErrStat := 200;
- EXIT
- END;
- Assign(VFile,Voicefile);
- Reset(VFile,1);
- SampleSize := Filesize(VFile);
- AllocateMem(VoiceBuff,SampleSize);
- { Insufficient memory for the VOC file }
- IF (VoiceBuff = NIL) THEN BEGIN
- Close(VFile);
- VOCGetBuffer := FALSE;
- VOCErrStat := 210;
- EXIT;
- END;
- Segs := 0;
- REPEAT
- Blockread(VFile,Ptr(seg(VoiceBuff^)+4096*Segs,Ofs(VoiceBuff^))^,$FFFF,Read
- );
- Inc(Segs);
- UNTIL Read = 0;
- Close(VFile);
- { File not in VOC format }
- IF (TypeCastType(VoiceBuff^)[0]<>'C') OR
- (TypeCastType(VoiceBuff^)[1]<>'r') THEN BEGIN
- VOCGetBuffer := FALSE;
- VOCErrStat := 220;
- EXIT;
- END;
- { Load successful }
- VOCGetBuffer := TRUE;
- VOCErrStat := 0;
- { Read header length from file }
- VOCFileHeaderLength := Ord(TypeCastType(VoiceBuff^)[20]);
- END;
- FUNCTION VOCFreeBuffer (VAR VoiceBuff : Pointer):BOOLEAN;
- {* INPUT : Buffer pointer
- * OUTPUT : None
- * PURPOSE : Frees memory allocated for VOC data. }
- BEGIN
- Regs.AH := $49;
- Regs.ES := seg(VoiceBuff^);
- MsDos(Regs);
- VOCFreeBuffer := TRUE;
- IF (Regs.AX = 7) OR (Regs.AX = 9) THEN BEGIN
- VOCFreeBuffer := FALSE;
- VOCErrStat := 300
- END;
- END;
- FUNCTION VOCGetVersion:WORD;
- {* INPUT : None
- * OUTPUT : Driver version number
- * PURPOSE : Returns driver version number. }
- VAR
- VDummy : WORD;
- BEGIN
- ASM
- MOV BX,0
- CALL VOCPtrToDriver
- MOV VDummy, AX
- END;
- VOCGetVersion := VDummy;
- END;
-
- PROCEDURE VOCSetPort(PortNumber : WORD);
- {* INPUT : Port address number
- * OUTPUT : None
- * PURPOSE : Specifies port address before initialization. }
- BEGIN
- ASM
- MOV BX,1
- MOV AX,PortNumber
- CALL VOCPtrToDriver
- END;
- END;
- PROCEDURE VOCSetIRQ(IRQNumber : WORD);
- {* INPUT : Interrupt number
- * OUTPUT : None
- * PURPOSE : Specifies interrupt number before initialization.}
- BEGIN
- ASM
- MOV BX,2
- MOV AX,IRQNumber
- CALL VOCPtrToDriver
- END;
- END;
- FUNCTION VOCInitDriver: BOOLEAN;
- {* INPUT : None
- * OUTPUT : Error message number, and initialization result
- * PURPOSE : Initializes driver software. }
- VAR
- Out, VSeg, VOfs : WORD;
- F : File;
- Drivername,
- Pdir : DirStr;
- Pnam : NameStr;
- Pext : ExtStr;
- BEGIN
- { Search path for CT-VOICE.DRV driver }
- Pdir := ParamStr(0);
- Fsplit(ParamStr(0),Pdir,Pnam,Pext);
- Drivername := Pdir+'CT-VOICE.DRV';
- VOCInitDriver := TRUE;
- { Driver file not found }
- IF Not Exists(Drivername) THEN BEGIN
- VOCInitDriver := FALSE;
- VOCErrStat := 100;
- EXIT;
- END;
- { Load driver }
- Assign(F,Drivername);
- Reset(F,1);
- AllocateMem(VOCPtrToDriver,Filesize(F));
- { No memory can be allocated for the driver }
- IF VOCPtrToDriver = NIL THEN BEGIN
- VOCInitDriver := FALSE;
- VOCErrStat := 110;
- EXIT;
- END;
- Blockread(F,VOCPtrToDriver^,Filesize(F));
- Close(F);
- { Driver file doesn't begin with "CT" - false driver }
- IF (TypeCastType(VOCPtrToDriver^)[3]<>'C') OR
- (TypeCastType(VOCPtrToDriver^)[4]<>'T') THEN BEGIN
- VOCInitDriver := FALSE;
- VOCErrStat := 120;
- EXIT;
- END;
- { Get version number and pass to global variable }
- VOCDriverVersion := VOCGetVersion;
- { Start driver }
- Vseg := Seg(VOCStatusWord);
- VOfs := Ofs(VOCStatusWord);
- ASM
- MOV BX,3
- CALL VOCPtrToDriver
- MOV Out,AX
- MOV BX,5
- MOV ES,VSeg
- MOV DI,VOfs
- CALL VOCPtrToDriver
- END;
- { No Sound Blaster card found }
- IF Out = 1 THEN BEGIN
- VOCInitDriver := FALSE;
- VOCErrStat := 400;
- EXIT;
- END;
- { False port address used }
- IF Out = 2 THEN BEGIN
- VOCInitDriver := FALSE;
- VOCErrStat := 410;
- EXIT;
- END;
- { False interrupt used }
- IF Out = 3 THEN BEGIN
- VOCInitDriver := FALSE;
- VOCErrStat := 420;
- EXIT;
- END;
- END;
- PROCEDURE VOCDeInstallDriver;
- {* INPUT : None
- * OUTPUT : None
- * PURPOSE : Disables driver and releases memory. }
- VAR
- Check : BOOLEAN;
- BEGIN
- IF VOCDriverInstalled THEN
- ASM
- MOV BX,9
- CALL VOCPtrToDriver
- END;
- Check := VOCFreeBuffer(VOCPtrToDriver);
- END;
- PROCEDURE VOCSetSpeaker(OnOff:BOOLEAN);
- {* INPUT : TRUE=Speaker on, FALSE=Speaker off
- * OUTPUT : None
- * PURPOSE : Sound Blaster output status. }
- VAR
- Switch : BYTE;
- BEGIN
- Switch := Ord(OnOff) AND $01;
- ASM
- MOV BX,4
- MOV AL,Switch
- CALL VOCPtrToDriver
- END;
- END;
- PROCEDURE VOCOutput (BufferAddress : Pointer);
- {* INPUT : Pointer to sample data
- * OUTPUT : None
- * PURPOSE : Plays sample. }
- VAR
- VSeg, VOfs : WORD;
- BEGIN
- VOCSetSpeaker(TRUE);
- VSeg := Seg(BufferAddress^);
- VOfs := Ofs(BufferAddress^)+VOCFileHeaderLength;
- ASM
- MOV BX,6
- MOV ES,VSeg
- MOV DI,VOfs
- CALL VOCPtrToDriver
- END;
- END;
- PROCEDURE VOCOutputLoop (BufferAddress : Pointer);
- {* Different from VOCOutput :
- * Speaker does not switch on with every sample output, so a
- * crackling noise may occur with some Sound Blaster cards. }
- VAR
- VSeg, VOfs : WORD;
- BEGIN
- VSeg := Seg(BufferAddress^);
- VOfs := Ofs(BufferAddress^)+VOCFileHeaderLength;
- ASM
- MOV BX,6
- MOV ES,VSeg
- MOV DI,VOfs
- CALL VOCPtrToDriver
- END;
- END;
- PROCEDURE VOCStop;
- {* INPUT : None
- * OUTPUT : None
- * PURPOSE : Stops a sample. }
- BEGIN
- ASM
- MOV BX,8
- CALL VOCPtrToDriver
- END;
- END;
- PROCEDURE VOCPause;
- {* INPUT : None
- * OUTPUT : None
- * PURPOSE : Pauses a sample. }
- VAR
- Switch : WORD;
- BEGIN
- VOCPaused := TRUE;
- ASM
- MOV BX,10
- CALL VOCPtrToDriver
- MOV Switch,AX
- END;
- IF (Switch = 1) THEN BEGIN
- VOCPaused := FALSE;
- VOCErrStat := 510;
- END;
- END;
- PROCEDURE VOCContinue;
- {* INPUT : None
- * OUTPUT : None
- * PURPOSE : Continues a paused sample. }
- VAR
- Switch : WORD;
- BEGIN
- ASM
- MOV BX,11
- CALL VOCPtrToDriver
- MOV Switch,AX
- END;
- IF (Switch = 1) THEN BEGIN
- VOCPaused := FALSE;
- VOCErrStat := 520;
- END;
- END;
- PROCEDURE VOCBreakLoop(BreakMode : WORD);
- {* INPUT : Break mode
- * OUTPUT : None
- * PURPOSE : Breaks a sample loop. }
- BEGIN
- ASM
- MOV BX,12
- MOV AX,BreakMode
- CALL VOCPtrToDriver
- MOV BreakMode,AX
- END;
- IF (BreakMode = 1) THEN VOCErrStat := 500;
- END;
- {$F+}
- PROCEDURE VoiceToolsExitProc;
- {$F-}
- {* INPUT : None
- * OUTPUT : None
- * PURPOSE : De-installs voice driver. }
- BEGIN
- VOCDeInstallDriver;
- ExitProc := OldExitProc;
- END;
- BEGIN
- {* The following statements execute automatically, as soon as the
- * unit is linked to a program, and the program starts. }
- { Replaces old ExitProc with new one from Tool unit }
- OldExitProc := ExitProc;
- ExitProc := @VoiceToolsExitProc;
- { Initialize values }
- VOCStatusWord := 0;
- VOCErrStat := 0;
- VOCPaused := FALSE;
- VOCFileHeaderLength := $1A;
- VOCFileHeader :=
- 'Creative Voice File'+#$1A+#$1A+#$00+#$0A+#$01+#$29+#$11+#$01;
- {* After installation, VOCDriverInstalled contains either TRUE or FALSE. }
- VOCDriverInstalled := VOCInitDriver;
- END.
-
-
- { ----------------------- DEMO PROGRAM --------------------------}
-
- PROGRAM VToolTest;
- {* VTTEST.PAS - uses VOCTOOL.TPU *}
-
- {$M 16000,0,50000}
- USES Crt,Voctool;
- VAR
- Sound : Pointer;
- Check : BOOLEAN;
- Ch : CHAR;
- PROCEDURE TextNumError;
- {* INPUT : None; data comes from the VOCErrStat global variable
- * OUTPUT : None
- * PURPOSE : Displays SB error on the screen as text, including the
- error number. Program then ends at the error level
- corresponding to the error number. }
- BEGIN
- Write(' Error #',VOCErrStat:3,' =');
- PrintVOCErrMessage;
- WriteLn;
- HALT(VOCErrStat);
- END;
-
- BEGIN
- ClrScr;
-
- { Driver not initialized }
- IF Not(VOCDriverInstalled) THEN TextNumError;
- { Loads DEMO.VOC file into memory }
- Check := VOCGetBuffer(Sound,'\SBPRO\MMPLAY\SBP.VOC');
- { VOC file could not be loaded }
- IF Not(Check) THEN TextNumError;
- { Main loop }
- Write('CT-Voice Driver Version : ');
- WriteLn(Hi(VOCDriverVersion),'.',Lo(VOCDriverVersion));
- WriteLn('(S)ingle play or (M)ultiple play?');
- Write('Press a key : '); Ch := ReadKey;WriteLn;WriteLn;
- CASE UpCase(Ch) OF
- 'S' : BEGIN
- Write('Press a key to stop the sound...');
- VOCOutput(Sound);
- REPEAT UNTIL KeyPressed OR (VOCStatusWord = 0);
- IF KeyPressed THEN VOCStop;
- END;
- 'M' : BEGIN
- Ch := #0;
- Write('Press <ESC> to cancel...');
- REPEAT
- VOCOutputLoop(Sound);
- REPEAT UNTIL KeyPressed OR (VOCStatusWord = 0);
- IF KeyPressed THEN Ch := ReadKey;
- UNTIL Ch = #27;
- VOCStop;
- END;
- END;
- { Free VOC file memory }
- Check := VOCFreeBuffer(Sound);
- IF Not(Check) THEN TextNumError;
- END.